import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:geolocator/geolocator.dart';
import 'package:geocoding/geocoding.dart';
import 'package:permission_handler/permission_handler.dart';
import '../models/weather_model.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import '../main.dart';

class WeatherService {
  static const String _caiyunToken = 'S6SCYpjVFCUrNP2b'; // 彩云天气API Token
  static const String _caiyunBaseUrl = 'https://api.caiyunapp.com/v2.6';

  // 检查并请求位置权限
  static Future<bool> _checkLocationPermission() async {
    final status = await Permission.location.request();
    return status.isGranted;
  }

  // 获取当前位置坐标
  static Future<Position> getCurrentPosition() async {
    final hasPermission = await _checkLocationPermission();
    if (!hasPermission) {
      throw Exception('位置权限被拒绝');
    }
    return await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.best,
    );
  }

  // 根据坐标获取城市名
  static Future<String> getCityFromCoordinates(double lon, double lat) async {
    try {
      final places = await placemarkFromCoordinates(lat, lon);
      if (places.isNotEmpty) {
        return places.first.locality ?? '当前位置';
      }
      return '当前位置';
    } catch (e) {
      return '当前位置';
    }
  }

  // 硬编码城市经纬度
  static final Map<String, List<double>> _hardcodedCities = {
    '北京': [116.4074, 39.9042],
    '上海': [121.4737, 31.2304],
    '广州': [113.2644, 23.1291],
    '深圳': [114.0579, 22.5431],
    '成都': [104.0668, 30.5728],
    '杭州': [120.1551, 30.2741],
    '武汉': [114.3055, 30.5928],
    '西安': [108.9480, 34.2631],
    '重庆': [106.5045, 29.5332],
    '南京': [118.7674, 32.0415],
    '昆明': [102.7122, 25.0406],
    '天津': [117.190169, 39.125596],
    '苏州': [120.619585, 31.299379],
    '青岛': [120.355152, 36.082982],
    '厦门': [118.103889, 24.489231],
    '哈尔滨': [126.642464, 45.756967],
    '沈阳': [123.429092, 41.792429],
    '大连': [121.614682, 38.914047],
    '济南': [117.000923, 36.675807],
    '郑州': [113.665412, 34.757975],
    '长沙': [112.982279, 28.19409],
    '福州': [119.306239, 26.075302],
    '南宁': [108.320004, 22.816002],
    '贵阳': [106.713478, 26.578343],
    '石家庄': [114.502461, 38.045474],
    '合肥': [117.283042, 31.86119],
    '南昌': [115.892751, 28.676495],
    '太原': [112.549248, 37.890277],
    '长春': [125.3245, 43.8868],
    '兰州': [103.792349, 36.059421],
    '呼和浩特': [111.738384, 40.818311],
    '银川': [106.278179, 38.46637],
    '西宁': [101.778916, 36.61717],
    '拉萨': [91.132212, 29.66037],
    '乌鲁木齐': [87.617733, 43.792818],
    '海口': [110.33119, 20.031971],
    '三亚': [109.511909, 18.2572],
    // 新增城市
    '宁波': [121.5497, 29.8683],
    '温州': [120.6721, 28.0130],
    '绍兴': [120.5826, 30.0515],
    '嘉兴': [120.7555, 30.7466],
    '湖州': [120.0868, 30.8944],
    '金华': [119.6495, 29.0895],
    '衢州': [118.8726, 28.9359],
    '台州': [121.4208, 28.6564],
    '丽水': [119.9232, 28.4518],
    '舟山': [122.2072, 29.9853],
    '徐州': [117.2841, 34.2058],
    '南通': [120.8564, 32.0162],
    '连云港': [119.2216, 34.5967],
    '淮安': [119.0213, 33.5975],
    '盐城': [120.1636, 33.3477],
    '扬州': [119.4129, 32.3942],
    '镇江': [119.4528, 32.2044],
    '泰州': [119.9152, 32.4849],
    '宿迁': [118.2752, 33.9630],
    '洛阳': [112.4540, 34.6197],
    '开封': [114.3073, 34.7971],
    '平顶山': [113.1927, 33.7669],
    '安阳': [114.3924, 36.0976],
    '鹤壁': [114.2954, 35.7482],
    '新乡': [113.9268, 35.3030],
    '焦作': [113.2418, 35.2159],
    '濮阳': [115.0293, 35.7618],
    '许昌': [113.8526, 34.0355],
    '漯河': [114.0264, 33.5818],
    '三门峡': [111.2001, 34.7732],
    '南阳': [112.5283, 32.9908],
    '商丘': [115.6564, 34.4142],
    '信阳': [114.0913, 32.1470],
    '周口': [114.6969, 33.6261],
    '驻马店': [114.0223, 32.9773],
    '济源': [112.6023, 35.0672],
    // 云南省城市
    '大理': [100.2257, 25.5894],
    '丽江': [100.2330, 26.8721],
    '西双版纳': [100.7974, 22.0094],
    '香格里拉': [99.7087, 27.8256],
    '玉溪': [102.5439, 24.3509],
    '曲靖': [103.7962, 25.4900],
    '保山': [99.1618, 25.1120],
    '昭通': [103.7172, 27.3382],
    '普洱': [100.9729, 22.7772],
    '临沧': [100.0796, 23.8776],
    '楚雄': [101.5460, 25.0430],
    '红河': [103.3846, 23.3642],
    '文山': [104.2442, 23.3695],
    '德宏': [98.5881, 24.4333],
    '怒江': [98.8543, 25.8607],
    '迪庆': [99.7030, 27.8189],
  };

  // 根据城市名称获取经纬度 (使用硬编码列表)
  static Future<List<double>> getCoordinatesFromCity(String city) async {
    print('尝试从硬编码列表获取城市经纬度: $city');
    if (_hardcodedCities.containsKey(city)) {
      final coordinates = _hardcodedCities[city]!;
      print('成功从硬编码列表获取城市经纬度: ${coordinates[0]}, ${coordinates[1]} for $city');
      return coordinates;
    } else {
      print('错误: 硬编码列表未找到该城市对应的经纬度: $city');
      throw Exception(
          '未找到该城市对应的经纬度。当前仅支持以下城市：${_hardcodedCities.keys.join('、')}');
    }
  }

  // AMap Web Service API for geocoding
  static const String _amapGeocodingUrl =
      'https://restapi.amap.com/v3/geocode/geo';
  static const String _amapApiKey =
      "cd112c7aa0dbf2f1f712f1fcc05fa794"; // 使用 Web 端 Key

  // 获取实况天气
  static Future<CaiyunRealtime> getRealtimeWeather(
      double lon, double lat) async {
    final url = '$_caiyunBaseUrl/$_caiyunToken/$lon,$lat/realtime';
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      return CaiyunRealtime.fromJson(data['result']['realtime']);
    } else {
      throw Exception('获取彩云实况天气失败');
    }
  }

  // 获取3天预报和生活指数
  static Future<Map<String, dynamic>> getDailyWeather(
      double lon, double lat) async {
    final url = '$_caiyunBaseUrl/$_caiyunToken/$lon,$lat/daily?dailysteps=3';
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      final daily = data['result']['daily'];
      return {
        'forecast':
            List.generate(3, (i) => CaiyunDailyForecast.fromJson(daily, i)),
        'lifeIndex': CaiyunLifeIndex.fromJson(daily['life_index']),
      };
    } else {
      throw Exception('获取彩云3天预报失败');
    }
  }

  // 获取48小时逐小时天气（用于前端切片连续24小时）
  static Future<List<Map<String, dynamic>>> getHourlyWeather(
      double lon, double lat) async {
    final url = '$_caiyunBaseUrl/$_caiyunToken/$lon,$lat/hourly?hourlysteps=48';
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final data = json.decode(response.body);
      final hourly = data['result']['hourly'];
      final List<dynamic> temperature = hourly['temperature'];
      final List<dynamic> skycon = hourly['skycon'];
      final List<dynamic> precipitation = hourly['precipitation'];
      List<Map<String, dynamic>> result = [];
      for (int i = 0; i < temperature.length; i++) {
        result.add({
          'datetime': DateTime.parse(temperature[i]['datetime']),
          'temp': temperature[i]['value'],
          'skycon': skycon[i]['value'],
          'precip': precipitation[i]['value'],
        });
      }
      // 按时间升序排序，确保数据顺序正确
      result.sort((a, b) => a['datetime'].compareTo(b['datetime']));
      return result;
    } else {
      throw Exception('获取彩云48小时预报失败');
    }
  }

  /// 检查极端天气并推送预警
  static void checkAndNotifyExtremeWeather(CaiyunRealtime weather) {
    String? alertType;
    String? alertMsg;
    if (weather.temperature >= 37) {
      alertType = '高温预警';
      alertMsg = '当前温度已达${weather.temperature}°C，请注意防暑降温。';
    } else if (weather.temperature <= 0) {
      alertType = '低温预警';
      alertMsg = '当前温度已降至${weather.temperature}°C，请注意保暖。';
    } else if (weather.skycon.contains('RAIN')) {
      alertType = '暴雨预警';
      alertMsg = '当前有降雨，请注意出行安全。';
    } else if (weather.skycon.contains('STORM')) {
      alertType = '强对流天气预警';
      alertMsg = '当前有强对流天气，请注意安全。';
    }
    if (alertType != null && alertMsg != null) {
      _showNotification(alertType, alertMsg);
    }
  }

  /// 检查自定义提醒条件并推送
  static void checkAndNotifyCustomReminders(
      CaiyunRealtime weather, List<CustomWeatherReminder> reminders) {
    for (final reminder in reminders) {
      if (!reminder.enabled) continue;
      bool shouldNotify = false;
      String msg = '';
      if (reminder.condition.contains('温度高于') && reminder.threshold != null) {
        if (weather.temperature > reminder.threshold!) {
          shouldNotify = true;
          msg = '当前温度${weather.temperature}°C，已超过设定阈值${reminder.threshold}°C';
        }
      } else if (reminder.condition.contains('温度低于') &&
          reminder.threshold != null) {
        if (weather.temperature < reminder.threshold!) {
          shouldNotify = true;
          msg = '当前温度${weather.temperature}°C，已低于设定阈值${reminder.threshold}°C';
        }
      } else if (reminder.condition.contains('下雨') ||
          (reminder.weatherType == '雨')) {
        if (weather.skycon.contains('RAIN')) {
          shouldNotify = true;
          msg = '当前有降雨，请注意携带雨具。';
        }
      }
      if (shouldNotify) {
        _showNotification('天气提醒', msg);
      }
    }
  }

  /// 推送本地通知
  static Future<void> _showNotification(String title, String body) async {
    const AndroidNotificationDetails androidPlatformChannelSpecifics =
        AndroidNotificationDetails(
      'weather_alerts',
      '天气提醒',
      channelDescription: '天气相关提醒和预警',
      importance: Importance.max,
      priority: Priority.high,
      showWhen: true,
    );
    const NotificationDetails platformChannelSpecifics =
        NotificationDetails(android: androidPlatformChannelSpecifics);
    await flutterLocalNotificationsPlugin.show(
      DateTime.now().millisecondsSinceEpoch ~/ 1000,
      title,
      body,
      platformChannelSpecifics,
    );
  }
}
